package logging

import (
	"context"
	"encoding/json"
	"fmt"
	"gitee.com/xiaotaozi/gocore/command"
	"go.uber.org/zap"
	"time"
)

func CreateCommandMiddleware[Request any,Response any](log *zap.SugaredLogger) command.Middleware[Request, Response] {
	return func(cmd command.Command[Request, Response]) command.Command[Request, Response] {
		return func(ctx context.Context, request Request) (Response, error) {
			start := time.Now()
			log.Infof("invoke command with argument [%s]",toString(request))
			// 注册回滚
			defer func() {
				if p := recover(); p != nil {
					log.Infof("command panic %v", toString(p), time.Since(start))
				}
			}()
			response,err := cmd(ctx, request)
			log.Infof("command finish whith [%s], cost %v", toString(response), time.Since(start))
			return response,err
		}
	}
}


func toString(argument interface{}) string{
	if argument == nil{
		return "nil"
	}
	if strer,ok := argument.(fmt.Stringer);ok{
		return strer.String()
	}
	// 尝试转json
	return ToJsonStringNotToBig(argument)
}

func ToJsonStringNotToBig(v interface{}) string{
	bytes,err := json.Marshal(v)
	if err == nil {
		str := string(bytes)
		if len(str) > 5000{
			return SubStringTo(str,0,5000)
		}
		return str
	}else{
		return "{\"error\":\""+ err.Error()+"\"}"
	}
}

func SubStringTo(str string,b int,e int) string{
	array := []rune(str)
	return string(array[b:e])
}